#include "table.h"

symbolTable* top = NULL;

void newTable()
{
    symbolTable* newtable = (symbolTable*)malloc(sizeof(symbolTable));
    newtable->root = RB_ROOT;
    newtable->pre = top;
    top = newtable;
    //printf("[debug] new table\n");
}

void deleteTable()
{
    assert(top != NULL);
    symbolTable* tmp = top;
    top = top->pre;
    freeMap(&(tmp->root), freeAttri);
    //printf("[debug] delete table\n");
}

void insertSymbol(char* key, void* val)
{
    assert(top != NULL);
    put(&(top->root),key,val);
    //printf("[debug] insert %s\n",key);
}

map_t* oneTableSearch(symbolTable* tmp, char* str)
{
    assert(tmp != NULL);
    map_t* target = get(&(tmp->root), str);
    return target;
}

map_t* allTableSearch(char* str)
{
    assert(top != NULL);
    symbolTable* tmp = top;
    map_t* target = NULL;
    while(tmp != NULL)
    {
        target = oneTableSearch(tmp, str);
        if(target != NULL) break;
        tmp = tmp->pre;
    }
    return target;
}

void printTable()
{
    symbolTable* tmpTable = top;
    while(tmpTable)
    {
        map_t* tmpMap = map_first(&(tmpTable->root));
        while(tmpMap)
        {
            printf("[new Var]\nkey: %s\nval: ",tmpMap->key);
            printAttri(tmpMap->val);
            tmpMap = map_next(&(tmpMap->node));
        }
        printf("\n\n");
        tmpTable = tmpTable->pre;
    }
}

bool isDupName(const char* varname) {
    if (oneTableSearch(top, varname) != NULL) return true;
    return false;
}

bool isMemparaDupName(const char* varname) {
    map_t* tmp = oneTableSearch(top, varname);
    if (tmp != NULL && ((attri*)(tmp->val))->type == STRUCTDEF) return true;
    return false;
}

bool isStructdefDupName(const char* varname){
    map_t* tmp = allTableSearch(varname);
    if (tmp != NULL && ((attri*)(tmp->val))->type == STRUCTDEF) return true;
    return false;
}